import time
import numpy as np
from RA_Cal import ReflectArray_cal_FFT, Para_RA, MASK_rp, Costfunction, csvtest
import random
import csv
import math
import matplotlib.pyplot as plt

def gray_to_binary(gray):
    binary = np.array([])
    nne = int(len(gray) / 4)
    for i in range(nne):
        ww = GrayCode_to_x(gray[i * 4: i * 4 + 4])
        binary = np.append(binary, ww)
    binary = np.array(binary, dtype=int)
    return binary

def GrayCode_to_x(x):
    x2 = np.array([x[0], x[0]^x[1], x[1]^x[2], x[2]^x[3]])
    return x2

def binary_to_gray(binary):
    gray = [binary[0]]
    for i in range(1, len(binary)):
        gray.append(binary[i - 1] ^ binary[i])
    return gray

def process_gray_code(gray_code):
    # Step 1: Convert Gray to Binary
    binary_code = gray_to_binary(gray_code)

    # Step 2: Split into 4-bit chunks and convert each to Gray
    chunk_size = 4
    chunks = [
        binary_code[i:i + chunk_size]
        for i in range(0, len(binary_code), chunk_size)
    ]
    final_gray = []
    for chunk in chunks:
        final_gray.extend(binary_to_gray(chunk))

    return final_gray

def Cut_theta(TT, phi0, RP):
    thaa_deg = np.linspace(0, 90, 181)
    thaa = thaa_deg / 180 * math.pi
    phi0 = phi0 / 180 * math.pi
    # print(thaa_deg)
    yy = []
    for thai in thaa:
        uu = math.sin(thai) * math.cos(phi0)
        vv = math.sin(thai) * math.sin(phi0)
        # print(uu)

        uq = int(uu*TT/2 + TT/2)
        vq = int(vv*TT/2 + TT/2)

        # print(uq, vq)
        yy.append(RP[min(uq, TT-1), min(vq, TT-1)])
    return thaa_deg, np.array(yy)

def Cut_phi(TT, theta0, RP):
    phii_deg = np.linspace(-180, 180, 361)
    phii = phii_deg / 180 * math.pi
    theta0 = theta0 / 180 * math.pi
    # print(thaa_deg)
    yy = []
    for phi in phii:
        uu = math.sin(theta0) * math.cos(phi)
        vv = math.sin(theta0) * math.sin(phi)
        # print(uu)
        uq = int(uu*TT/2 + TT/2)
        vq = int(vv*TT/2 + TT/2)

        # print(uq, vq)
        yy.append(RP[min(uq, TT-1), min(vq, TT-1)])
    return phii_deg, np.array(yy)

if __name__ == '__main__':
    Code_bestsofar = csvtest.Read_csv_inrows(r"CASE1_FI\Code_case2.csv", range(int(952*4)))[0, :]
    Code_bestsofar = np.array(Code_bestsofar, dtype=int)
    # print(np.shape(Code_bestsofar))
    # zvv = process_gray_code(Code_bestsofar)
    # print(np.shape(zvv))

    # with open("Code_case3_BACK.csv", 'a', encoding='utf-8', newline='') as f:
    #     write = csv.writer(f)
    #     write.writerow(list(zvv))
    TTT = 180
    Costfunction_400 = Costfunction.Costfunction_tt(TTT)
    # popu_rand = [random.randint(0, 1) for _ in range(len(Code_bestsofar))]

    # st = time.time()
    # print(Costfunction_400.CostFunction(0, Code_bestsofar))
    # print("cf time: ", time.time()-st)

    print("")
    print(Costfunction_400.CostFunction(1, Code_bestsofar))
    fxtt = Costfunction_400.RA.fxt
    lg_fxt = 10 * np.log10(fxtt)

    thetadeg, fxt_cut0 = Cut_theta(TTT, 0, lg_fxt)
    thetadeg0, fxt_cut10 = Cut_theta(TTT, 100, lg_fxt)
    thetadeg1, fxt_cut20 = Cut_theta(TTT, 200, lg_fxt)
    thetadeg2, fxt_cut30 = Cut_theta(TTT, 280, lg_fxt)
    plt.plot(thetadeg, fxt_cut0, thetadeg, fxt_cut10, thetadeg, fxt_cut20, thetadeg, fxt_cut30,)
    plt.grid()
    plt.show()

    # ppdeg, fxt_cut25 = Cut_phi(TTT, 25, lg_fxt)
    # plt.plot(ppdeg, fxt_cut25)
    # plt.grid()
    # plt.show()

    # with open("case3_theory_phi.csv", 'a', encoding='utf-8', newline='') as f:
    #     write = csv.writer(f)
    #     write.writerow(list(ppdeg.round(5)))
    #     write.writerow(list(fxt_cut25.round(5)))

    # with open("case2_theory_theta.csv", 'a', encoding='utf-8', newline='') as f:
    #     write = csv.writer(f)
    #     write.writerow(list(thetadeg.round(5)))
    #     write.writerow(list(fxt_cut0.round(5)))
    #     write.writerow(list(fxt_cut10.round(5)))
    #     write.writerow(list(fxt_cut20.round(5)))
    #     write.writerow(list(fxt_cut30.round(5)))

    print("")
    print(Costfunction_400.CostFunction_View(1, Code_bestsofar))
    print("")